# 指定文件编码为UTF-8
# coding: utf-8

"""
layer_naive.py 功能说明：
1. 实现神经网络中的基本计算层：乘法层(MulLayer)和加法层(AddLayer)
2. 每个计算层都包含正向传播(forward)和反向传播(backward)方法
3. 乘法层用于实现变量间的乘积运算(如价格×数量)
4. 加法层用于实现变量间的求和运算(如多项价格求和)
5. 为构建复杂神经网络提供基础计算单元

关键点：
- 采用计算图(computational graph)的思想实现
- 正向传播计算结果，反向传播计算梯度
- 乘法层的反向传播需要交换输入值
- 加法层的反向传播直接传递梯度
- 各层保持计算过程的独立性
"""

# 乘法层实现类
class MulLayer:
    # 初始化方法
    def __init__(self):
        # 保存正向传播时的输入值，用于反向传播计算
        self.x = None  # 存储第一个输入
        self.y = None  # 存储第二个输入

    # 正向传播方法
    def forward(self, x, y):
        # 保存输入值
        self.x = x
        self.y = y
        # 计算乘积并返回
        out = x * y
        return out

    # 反向传播方法
    def backward(self, dout):
        # 计算关于x的梯度(上游梯度×y)
        dx = dout * self.y
        # 计算关于y的梯度(上游梯度×x)
        dy = dout * self.x
        # 返回两个梯度
        return dx, dy


# 加法层实现类
class AddLayer:
    # 初始化方法(无需保存状态)
    def __init__(self):
        pass  # 加法层不需要保存中间变量

    # 正向传播方法
    def forward(self, x, y):
        # 计算和并返回
        out = x + y
        return out

    # 反向传播方法
    def backward(self, dout):
        # 关于x的梯度(上游梯度×1)
        dx = dout * 1
        # 关于y的梯度(上游梯度×1)
        dy = dout * 1
        # 返回两个梯度
        return dx, dy

"""
使用示例：
1. 乘法层示例：
   apple = 100; apple_num = 2
   mul_layer = MulLayer()
   price = mul_layer.forward(apple, apple_num)  # 正向计算
   dapple, dapple_num = mul_layer.backward(1.0) # 反向传播

2. 加法层示例：
   apple_price = 200; orange_price = 150
   add_layer = AddLayer()
   total = add_layer.forward(apple_price, orange_price)  # 正向计算
   dapple, dorange = add_layer.backward(1.0)  # 反向传播

注意：
- 反向传播时的dout参数表示从上游传来的梯度
- 乘法层需要保存正向传播的输入值用于反向计算
- 加法层的反向传播直接将梯度分发给所有输入
"""
